/**
 * Canvas分享卡片绘制工具
 * 用于生成打卡分享卡片图片
 */

import type { PunchRecordRespVO } from '@/api/types/punch'

// 分享卡片配置
export interface ShareCardConfig {
  width: number
  height: number
  padding: number
  backgroundColor: string
  borderRadius: number
}

// 默认配置
const DEFAULT_CONFIG: ShareCardConfig = {
  width: 750,
  height: 1000,
  padding: 40,
  backgroundColor: '#f0f9ff',
  borderRadius: 20,
}

// 颜色配置
const COLORS = {
  primary: '#42bbff',
  secondary: '#87ceeb',
  text: '#1e293b',
  textSecondary: '#94a3b8',
  white: '#ffffff',
  success: '#32cd32',
  gradient: {
    blue: ['#42bbff', '#87ceeb'],
    green: ['#32cd32', '#98fb98'],
  },
}

// 字体配置
const FONTS = {
  title: 'bold 32px PingFang SC, sans-serif',
  subtitle: '24px PingFang SC, sans-serif',
  body: '20px PingFang SC, sans-serif',
  small: '16px PingFang SC, sans-serif',
}

/**
 * 加载图片
 */
export function loadImage(src: string): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.crossOrigin = 'anonymous'
    img.onload = () => resolve(img)
    img.onerror = reject
    img.src = src
  })
}

/**
 * 绘制圆角矩形
 */
export function drawRoundedRect(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number) {
  ctx.beginPath()
  ctx.moveTo(x + radius, y)
  ctx.lineTo(x + width - radius, y)
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
  ctx.lineTo(x + width, y + height - radius)
  ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
  ctx.lineTo(x + radius, y + height)
  ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
  ctx.lineTo(x, y + radius)
  ctx.quadraticCurveTo(x, y, x + radius, y)
  ctx.closePath()
}

/**
 * 绘制渐变背景
 */
export function drawGradientBackground(ctx: CanvasRenderingContext2D, width: number, height: number, colors: string[]) {
  const gradient = ctx.createLinearGradient(0, 0, 0, height)
  colors.forEach((color, index) => {
    gradient.addColorStop(index / (colors.length - 1), color)
  })
  ctx.fillStyle = gradient
  ctx.fillRect(0, 0, width, height)
}

/**
 * 绘制文字（支持换行）
 */
export function drawText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, maxWidth: number, lineHeight: number, maxLines?: number) {
  const words = text.split('')
  let line = ''
  let currentY = y
  let lineCount = 0

  for (let i = 0; i < words.length; i++) {
    const testLine = line + words[i]
    const metrics = ctx.measureText(testLine)
    const testWidth = metrics.width

    if (testWidth > maxWidth && line !== '') {
      ctx.fillText(line, x, currentY)
      line = words[i]
      currentY += lineHeight
      lineCount++

      if (maxLines && lineCount >= maxLines) {
        // 如果超过最大行数，添加省略号
        if (i < words.length - 1) {
          const ellipsisLine = `${line.slice(0, -3)}...`
          ctx.fillText(ellipsisLine, x, currentY)
        }
        break
      }
    }
    else {
      line = testLine
    }
  }

  if (line && (!maxLines || lineCount < maxLines)) {
    ctx.fillText(line, x, currentY)
  }

  return currentY + lineHeight
}

/**
 * 绘制圆形图片
 */
export function drawCircleImage(ctx: CanvasRenderingContext2D, img: HTMLImageElement, x: number, y: number, radius: number) {
  ctx.save()
  ctx.beginPath()
  ctx.arc(x + radius, y + radius, radius, 0, Math.PI * 2)
  ctx.clip()
  ctx.drawImage(img, x, y, radius * 2, radius * 2)
  ctx.restore()
}

/**
 * 绘制圆角图片
 */
export function drawRoundedImage(ctx: CanvasRenderingContext2D, img: HTMLImageElement, x: number, y: number, width: number, height: number, radius: number) {
  ctx.save()
  drawRoundedRect(ctx, x, y, width, height, radius)
  ctx.clip()
  ctx.drawImage(img, x, y, width, height)
  ctx.restore()
}

/**
 * 生成分享卡片
 */
export async function generateShareCard(punchData: PunchRecordRespVO, userInfo?: { avatar?: string, nickname?: string }, config: Partial<ShareCardConfig> = {}): Promise<string> {
  const finalConfig = { ...DEFAULT_CONFIG, ...config }

  // 在小程序环境中使用uni.createCanvasContext
  // 这里先返回一个占位图片，实际实现需要在小程序中使用canvas组件
  if (typeof uni !== 'undefined') {
    // 小程序环境，返回默认分享图片
    console.log('小程序环境，使用默认分享图片')
    return '/static/images/default-share.png'
  }

  // Web环境的Canvas实现
  const canvas = document.createElement('canvas')
  canvas.width = finalConfig.width
  canvas.height = finalConfig.height
  const ctx = canvas.getContext('2d')!

  try {
    // 1. 绘制背景
    drawGradientBackground(ctx, finalConfig.width, finalConfig.height, [
      '#f0f9ff',
      '#e0f2fe',
      '#bae6fd',
    ])

    // 2. 绘制主卡片背景
    const cardX = finalConfig.padding
    const cardY = finalConfig.padding
    const cardWidth = finalConfig.width - finalConfig.padding * 2
    const cardHeight = finalConfig.height - finalConfig.padding * 2

    ctx.fillStyle = COLORS.white
    ctx.shadowColor = 'rgba(0, 0, 0, 0.1)'
    ctx.shadowBlur = 20
    ctx.shadowOffsetY = 10
    drawRoundedRect(ctx, cardX, cardY, cardWidth, cardHeight, finalConfig.borderRadius)
    ctx.fill()
    ctx.shadowColor = 'transparent'

    // 3. 绘制头部区域
    let currentY = cardY + 60

    // 用户头像和信息
    if (userInfo?.avatar) {
      try {
        const avatarImg = await loadImage(userInfo.avatar)
        drawCircleImage(ctx, avatarImg, cardX + 40, currentY - 30, 30)
      }
      catch (error) {
        console.warn('头像加载失败:', error)
      }
    }

    // 用户昵称
    ctx.fillStyle = COLORS.text
    ctx.font = FONTS.subtitle
    ctx.fillText(userInfo?.nickname || '小读者', cardX + 120, currentY)

    // 打卡日期
    ctx.fillStyle = COLORS.textSecondary
    ctx.font = FONTS.small
    const dateText = formatShareDate(punchData.punchDate)
    ctx.fillText(dateText, cardX + 120, currentY + 30)

    currentY += 100

    // 4. 绘制阅读统计
    const statsY = currentY
    const statWidth = (cardWidth - 120) / 3

    // 统计背景
    ctx.fillStyle = '#f8fafc'
    drawRoundedRect(ctx, cardX + 40, statsY, cardWidth - 80, 120, 16)
    ctx.fill()

    // 绘制统计数据
    const stats = [
      { label: '本绘本', value: punchData.bookCount.toString() },
      { label: '连续天', value: punchData.dayCount.toString() },
      { label: '已打卡', value: '✓' },
    ]

    stats.forEach((stat, index) => {
      const statX = cardX + 40 + index * statWidth + statWidth / 2

      // 数值
      ctx.fillStyle = COLORS.primary
      ctx.font = FONTS.title
      ctx.textAlign = 'center'
      ctx.fillText(stat.value, statX, statsY + 50)

      // 标签
      ctx.fillStyle = COLORS.textSecondary
      ctx.font = FONTS.small
      ctx.fillText(stat.label, statX, statsY + 80)
    })

    ctx.textAlign = 'left'
    currentY = statsY + 160

    // 5. 绘制绘本封面
    if (punchData.books && punchData.books.length > 0) {
      const booksToShow = punchData.books.slice(0, 4) // 最多显示4本
      const bookSize = 80
      const bookSpacing = 20
      const totalBooksWidth = booksToShow.length * bookSize + (booksToShow.length - 1) * bookSpacing
      const booksStartX = cardX + (cardWidth - totalBooksWidth) / 2

      for (let i = 0; i < booksToShow.length; i++) {
        const book = booksToShow[i]
        const bookX = booksStartX + i * (bookSize + bookSpacing)

        try {
          if (book.cover) {
            const bookImg = await loadImage(book.cover)
            drawRoundedImage(ctx, bookImg, bookX, currentY, bookSize, bookSize * 1.2, 8)
          }
          else {
            // 绘制默认书籍图标
            ctx.fillStyle = '#e2e8f0'
            drawRoundedRect(ctx, bookX, currentY, bookSize, bookSize * 1.2, 8)
            ctx.fill()

            ctx.fillStyle = COLORS.textSecondary
            ctx.font = FONTS.small
            ctx.textAlign = 'center'
            ctx.fillText('📚', bookX + bookSize / 2, currentY + bookSize * 0.6)
          }
        }
        catch (error) {
          console.warn('绘本封面加载失败:', error)
          // 绘制默认图标
          ctx.fillStyle = '#e2e8f0'
          drawRoundedRect(ctx, bookX, currentY, bookSize, bookSize * 1.2, 8)
          ctx.fill()
        }
      }

      currentY += bookSize * 1.2 + 40
    }

    // 6. 绘制打卡心得
    if (punchData.commentText) {
      ctx.fillStyle = COLORS.text
      ctx.font = FONTS.body
      ctx.textAlign = 'left'

      const commentMaxWidth = cardWidth - 80
      const commentText = punchData.commentText.length > 50
        ? `${punchData.commentText.substring(0, 50)}...`
        : punchData.commentText

      drawText(ctx, `"${commentText}"`, cardX + 40, currentY, commentMaxWidth, 30, 3)
      currentY += 100
    }

    // 7. 绘制底部信息
    const bottomY = cardY + cardHeight - 80

    // 应用名称和邀请文字
    ctx.fillStyle = COLORS.textSecondary
    ctx.font = FONTS.small
    ctx.textAlign = 'center'
    ctx.fillText('一起来阅读绘本吧！', finalConfig.width / 2, bottomY)

    ctx.fillStyle = COLORS.primary
    ctx.font = FONTS.subtitle
    ctx.fillText('绘本阅读小程序', finalConfig.width / 2, bottomY + 30)

    // 返回base64图片
    return canvas.toDataURL('image/png', 0.8)
  }
  catch (error) {
    console.error('生成分享卡片失败:', error)
    throw error
  }
}

/**
 * 格式化分享日期
 */
function formatShareDate(dateStr: string): string {
  const date = new Date(dateStr)
  const today = new Date()

  if (date.toDateString() === today.toDateString()) {
    return '今天打卡'
  }

  return `${date.getMonth() + 1}月${date.getDate()}日打卡`
}
